איך מחברים את הCI לDB ושימוש בModel
DB
הCI מגיע עם ספריות DB נרחבות ומאפשר לנו שימוש קל ברוב הDB הידועים,
לפי הדוקומנטציה הוא תומך בMySQL (4.1+), MySQLi, MS SQL, Postgres, Oracle, SQLite, and ODBC.
ומדי פעם עוד מוסיפים לו תמיכה בעוד..
החיבור לDB כלשהו הוא מאוד פשוט, תחת ספריית הapplication/config יש לנו קובץ בשם database.php שנראה כך:
$active_group = 'default';
$active_record = TRUE;
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = '';
$db['default']['password'] = '';
$db['default']['database'] = '';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
$active_record = TRUE;
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = '';
$db['default']['password'] = '';
$db['default']['database'] = '';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
כדי להתחבר לDB ראשית עליכם למלא את ההגדרות הנכונות תחת username,passeord ו database.
בשלב זה הCI יוכל להתחבר לDB אם נרצה בכך אך אין זה מספיק, CI לא טוען שום קלאס מעצמו, וזו אחת הסיבות שהוא כל כך קל משקל.
כדי שהוא יתחבר db_demo עלינו להגיד לו לעשות זאת, ולשם כך נייצר קונטרולר בשם application/controllers/db_demo.php.
class Db_demo extends CI_Controller{
function index(){
$this->load->database();
}
}
function index(){
$this->load->database();
}
}
הפקודה $this->load->database(); טוענת את כל הקלאסים שנדרשים בשביל חיבור לDB כולל קלאס ייחודי שנקרא active_record (שמאפשר לנו כתיבת SQL קל נקי ומהיר) ועליו נרחיב בהמשך.
נסו להריץ את התוכנית לעייל, ואם לא קיבלתם שום הודעת שגיאה (מסך לבן!) זה אומר שהכל עבר כמו שצריך..
תזכורת, פקודת ההרצה תהיה:
http://localhost/CI/db_demo
חיבור קבוע וautoload
כיוון שלרוב נרצה את החיבור לDB בכל הפרוייקט או לפחות בכל הקונטרולר ולא נרצה אותו בכל מתודה, ניתן לשים את פקודת החיבור ככה שהDB יהיה זמין לנו בכל מקום.
כפי שציינתי בעבר הCI לא טוען שום דבר אוטומטית ורק לאחר שאנחנו מבקשים ממנו לטעון משהו הוא עושה את זה, אבל ישנם משאבים שאנחנו נרצה איתנו בכל הפרוייקט, לשם כך ישנו הקובץ application/config/autoload.php
בקובץ זה ניתן להגדיר איזה משאבים אנחנו רוצים שהCI יטען בכל פעם שהוא עולה.
אם כן פתחו את בקובץ אתרו את השורה הבאה:
$autoload['libraries'] = array();
והחליפו אותה ב:
$autoload['libraries'] = array('database');
מעתה החיבור לDB יטען אוטומטית עבורנו ואין צורך לטעון אותו ידנית.
שימוש בסביבות שונות
לרוב אנחנו צריכים הגדרות חיבור שונות עבור כל סביבה, לשם כך ניתן להגדיר DB group, ולהתאים אותו לסביבה שלנו, לדוגמא הקוד הבא מאפשר שימוש בחיבור שונה בproduction, כמובן שתוכלו להוסיף סביבות כיד הדמיון או לפי הצורך...
$active_group = 'default';
if(ENVIRONMENT=='production')$active_group = 'production';
$active_record = TRUE;
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = '[local user]';
$db['default']['password'] = '[local pass]';
$db['default']['database'] = '[local db]';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
$db['production']['hostname'] = 'localhost';
$db['production']['username'] = '[prod user]';
$db['production']['password'] = '[prod pass]';
$db['production']['database'] = '[prod db]';
$db['production']['dbdriver'] = 'mysql';
$db['production']['dbprefix'] = '';
$db['production']['pconnect'] = TRUE;
$db['production']['db_debug'] = TRUE;
$db['production']['cache_on'] = FALSE;
$db['production']['cachedir'] = '';
$db['production']['char_set'] = 'utf8';
$db['production']['dbcollat'] = 'utf8_general_ci';
$db['production']['swap_pre'] = '';
$db['production']['autoinit'] = TRUE;
$db['production']['stricton'] = FALSE;
if(ENVIRONMENT=='production')$active_group = 'production';
$active_record = TRUE;
$db['default']['hostname'] = 'localhost';
$db['default']['username'] = '[local user]';
$db['default']['password'] = '[local pass]';
$db['default']['database'] = '[local db]';
$db['default']['dbdriver'] = 'mysql';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;
$db['production']['hostname'] = 'localhost';
$db['production']['username'] = '[prod user]';
$db['production']['password'] = '[prod pass]';
$db['production']['database'] = '[prod db]';
$db['production']['dbdriver'] = 'mysql';
$db['production']['dbprefix'] = '';
$db['production']['pconnect'] = TRUE;
$db['production']['db_debug'] = TRUE;
$db['production']['cache_on'] = FALSE;
$db['production']['cachedir'] = '';
$db['production']['char_set'] = 'utf8';
$db['production']['dbcollat'] = 'utf8_general_ci';
$db['production']['swap_pre'] = '';
$db['production']['autoinit'] = TRUE;
$db['production']['stricton'] = FALSE;
Models
כעת לאחר שהתחברנו לDB, אנחנו נלמד על השימוש במודלים, למי ששכח תפקיד המודל הוא להיות שכבה שמחברת בין התוכנית שלנו לבין מקור הנתונים, זה יכול להיות כל דבר החל בDB עובר לXML JSON CSV TXT או כל מקור שממנו אתם רוצים למשוך/לכתוב מידע.
הרעיון הוא שכל הכתיבות קריאות יעברו דרך מקום אחד וכך תהיה לנו יותר שליטה וריכוז של הפניות למקור המידע, קצת כמו הרעיון של getters וsetters למשתני private בOOP.
(ולכל מי שכבר מתחיל לכתוב לי תגובה נזעמת, הbusiness logic לא יושב כאן אלא בlibraries, תפקיד המודל הוא להיות השכבה המחברת לdata source ותו לא!)
Hellow World - Model
לשם הדוגמא הבאה אנא הריצו את פקודות הSQL הבאות בphpmyadmin או בקליינט הSQL הקרוב לביתכם:
CREATE DATABASE `demo` /*!40100 DEFAULT CHARACTER SET utf8 */;
CREATE TABLE `demo`.`users` (
`u_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`u_first` VARCHAR(45),
`u_last` VARCHAR(45),
`u_email` VARCHAR(255) NOT NULL,
`u_pass` VARCHAR(45),
PRIMARY KEY (`u_id`)
)
ENGINE = InnoDB;
INSERT INTO `users` (`u_id`, `u_first`, `u_last`, `u_email`, `u_pass`) VALUES
(1, 'Alon', 'Nagar', '[email protected]', '1234'),
(2, 'Menashe', 'CI', '[email protected]', '4321'),
(3, 'Yair', 'CodeIgniter', '[email protected]', '1111'),
(4, 'Amichai', 'CI', '[email protected]', '2222');
CREATE TABLE `demo`.`users` (
`u_id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
`u_first` VARCHAR(45),
`u_last` VARCHAR(45),
`u_email` VARCHAR(255) NOT NULL,
`u_pass` VARCHAR(45),
PRIMARY KEY (`u_id`)
)
ENGINE = InnoDB;
INSERT INTO `users` (`u_id`, `u_first`, `u_last`, `u_email`, `u_pass`) VALUES
(1, 'Alon', 'Nagar', '[email protected]', '1234'),
(2, 'Menashe', 'CI', '[email protected]', '4321'),
(3, 'Yair', 'CodeIgniter', '[email protected]', '1111'),
(4, 'Amichai', 'CI', '[email protected]', '2222');
לאחר שבניתם DB וודאו שהוא מוגדר נכון תחת config/database.php.
בתוכנית הבאה אני מתבסס על כך שהוספתם את הdatabase לconfig/autoload.php. כפי שהסברתי מקודם, אם עוד לא עשיתם זאת זה הזמן.
Users Model
כדי להשתמש במידע שהכנסנו לDB אנחנו נייצר model שייגש אליו, אנא צרו תחת תיקיית application/model את הקובץ (אותיות קטנות!) users_model.php
class Users_Model extends CI_Model{
public function getAll(){
//query the db
$resObj = $this->db->query("SELECT * FROM `users`");
//if there are results
if($resObj->num_rows()){
//return the results as array
return $resObj->result_array();
}
else{
//return empty array
return array();
}
}
}
public function getAll(){
//query the db
$resObj = $this->db->query("SELECT * FROM `users`");
//if there are results
if($resObj->num_rows()){
//return the results as array
return $resObj->result_array();
}
else{
//return empty array
return array();
}
}
}
לאחר שטענו חיבור לdatabase, מתווסף הן בקונטרולר והן במודל מאפיין שנקרא db, למאפיין הזה ישנה מתודה שנקראת query() ודרכה אנחנו יכולים לבצע שאילתות על הDB.
התשובה חוזרת כאובייקט מיוחד של CI, וראשית אני בודק האם חזרו תוצאות if($resObj->num_rows()) אם כן אני מחזיר את התוצאות כמערך גדול return $resObj->result_array(); אחרת אני מחזיר מערך ריק.
users Controller
לשם שימוש בmodel אנא צרו את הקונטרולר application/controller/users.php
class Users extends CI_Controller{
function show(){
//load the model
$this->load->model("users_model");
//fetch the users
$data['usersArr'] = $this->users_model->getAll();
//send to view
$this->load->view("users/show_view",$data);
}
}
function show(){
//load the model
$this->load->model("users_model");
//fetch the users
$data['usersArr'] = $this->users_model->getAll();
//send to view
$this->load->view("users/show_view",$data);
}
}
כאן אנחנו יכולים להתחיל לראות את הכח שהשימוש במודל נותן לנו, מעכשיו כל פעם שנרצה למשוך את כל היוזרים רק נצטרך לקרוא למודל, וזהו!
שימו לב שכדי להשתמש במודל שכתבנו חייבים לטעון אותו באמצעות המתודה $this->load->model() בטח כבר הבנתם ששום דבר לא נטען לבד בCI, ניתן לטעון מודלים בconfig/autoload.php אבל זו שיטה לא נכונה כיוון שזה אומר שהמודל יטען בכל מקום במערכת.
גישה נכונה יותר שאותה נלמד בהמשך היא לטעון אותו ב__construct() של הקונטרולר, כיוון שכן נצטרך את המודל הזה בכל מקום בקונטרולר.
view
לשם הצגת הרשימה אנא צרו את התיקייה users תחת application/views ותחתיה צרו את הקובץ show_view.php
<html>
<head>
<title>users model usage</title>
</head>
<body>
<h1>Users list</h1>
<table>
<tr>
<th>#</th>
<th>First</th>
<th>Last</th>
<th>Email</th>
</tr>
<?php foreach ($usersArr as $user):?>
<tr>
<td><?php echo $user['u_id']?></td>
<td><?php echo $user['u_first']?></td>
<td><?php echo $user['u_last']?></td>
<td><?php echo $user['u_email']?></td>
</tr>
<?php endforeach;?>
</table>
</body>
</html>
<head>
<title>users model usage</title>
</head>
<body>
<h1>Users list</h1>
<table>
<tr>
<th>#</th>
<th>First</th>
<th>Last</th>
<th>Email</th>
</tr>
<?php foreach ($usersArr as $user):?>
<tr>
<td><?php echo $user['u_id']?></td>
<td><?php echo $user['u_first']?></td>
<td><?php echo $user['u_last']?></td>
<td><?php echo $user['u_email']?></td>
</tr>
<?php endforeach;?>
</table>
</body>
</html>
כמו שניתן לראות קיבלנו בview את מערך המשתמשים, כל איבר במערך הוא רשומה אחת מתוך הDB כאשר ברשומה כל key הוא עמודה מהDB.
כדי להריץ את התוכנית להלן אנא הריצו את:
http://localhost/CI/users/show
תגובות לכתבה:
+1
אחלה מדריך !
תודה רבה, מה הדרך הנכונה לחלק.ליצור Model clases?
ז"א, האם עושים מודל עבור כל קונטרולר או שאיך?
בונים מודל עבור כל טבלה במסד נתונים + אם רוצים לבצע עוד מקור נתונים, אז גם בשבילו..
אבל אם אני צריך לעשות JOINים עם 5-7 טבלאות, אז עבור הJOIN הזה אני עושה MODEL?
אז אתה עושה אותו במודל של הטבלה הראשית של ה-join.
ב-Yii אתה מקבל כבר קוד מגניב אוטומתי שמטפל בזה באמת בצורה יפה.
הנה דוגמא: http://www.yiiframework.com/doc/guide/1.1/en/database.arr
הבנתי, פשוט אני עובד על FW אישי שלי...(איתו הכי נוח לי לעבוד)
ואני לא הצלחתי להבין איך אני גורם לעניין של הmodelים לעבוד. עכשיו זה קצת יותר בהיר.
עוד שאלה, במודל "שיושב" מעל טבלה מסויימת, כל סוג שליפה (מלבד הבסיסיים) יהיה בעצם מתודה?
אפשר גם.. ואפשר לא.
תלוי בצרכים שלך.
אם אתה כל כך רוצה לבנות FW משלך.. תעבוד קצת עם FW רגיל, ותראה איך עובדים נכון.. ואולי תצליח לבנות לעצמך FW שיעבוד נכון.
עדיין, הכי מומלץ זה לעבוד על פי סטנדרט כתיבה מסויים, ו-FW אישי, לא מביא לך את זה.
אני מעלה את הcodigniter מxampp במחשב שלי שהכל תקין
לשרת לינוקס אפאצי עם דומיין ומקבל הודעה ...
בפיסי שלי הכל תקין הבעיה שזה בשרת .
קונפג config.php לדומיין הנכון .
וגם database.php
להלן ההודעה
Fatal error: Class 'ALS_Model' not found in /home/allsea/public_html/pam/application/models/admin/kom.php on line 3
ניתן לראות אותה בלינק זה http://allsearch.co.il/pam
.htaccess - מקונפג כך
RewriteEngine on
RewriteCond $1 !^(index\.php|utils|robots\.txt)
RewriteRule ^(.*)$ /pam/index.php/$1 [L]
אודה על עזרה .
מה שמוזר שאצלי במחשב הוא מזהה את כל המודלים היטב עם אפצי ..
וגם בשרת iis קינפגתי את web.config והכל תקין .
פה יש הפניה מה.htaccess אבל עדיין לא מזהה את המודלי טעינה.
סביר מאוד שהבעיה היא עם שמות קבצים...
שם הקובץ חייב להיות באותויות קטנות
**אותיות
תודה רבה אלון ......... חבל שקודגhנאטור לא מבין זאת שיש גם לינקוס
למה כל הקבצים שלו עם אותיות גדולות וקטנות והאם צריך את כולם לתקן או רק את הclass?
כרגע המתכנת שלנו נכנס והכניס require לכל class ...בכל קובץ בשרשרת .
האם יש פתרון יותר טוב או שככה עובדים ופשוט תחת וינדוס הכל מוכר .
אלון ,
האם יש איזה מסמך שמראה לי את קבצי מערכת אני צריך לשנות בלינוקס ?
כי הלכתי לאיבוד שם וחלק מהדברים עובדים וחלק לא עובדים אודה על עזרתך .
אודי
לא צריך לשנות כלום,
רק תוודא שכל הקבצים שאתה מייצר הם באותיות קטנות, ו.... זהו!
מדריכים מצויינים, מחכה לעוד :)
שלום אלון , קודם כל מדריכים מובנים מעולים , אני רוצה לכתוב נגיד class user ויש לו שדות private , לפני הבנתי בכל מני מדריכים באינטרנט שאני צריך לשמור את class בתקיה libraries ואז מתוך contrller לטעון לקלאס באותה פונקציה של טעינה אני יכול שלוח לconstrctor של קלאס את משתנים לאתחול שדות של אובייקט , אחרי שאני עושה , יש לי באותו קלאס פוניציה get שמחזירה שדה של אובייקט , לדוגמה getName
ואני מנסה לדפיס מתוך controler את ערך שדה הוא לא מחיזר לי כלום , יש אפשרות מסיבר לי או יש לי מדריך לזה , או שאפשר בדרך רגילה לכתוב קלאס ולעשות include לקובץ של קלאס
הסתדרתי תודה
סיימתי את המדריך ..
ממש טוב תודה !!
אולי תמשיך אותו אתה מסביר טוב